package de.herberlin.showheader;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;

import javax.swing.Timer;

/**
 * Network Request openes a socket to the 
 * choosen host and performs a http-request 
 * in a separate Thread.
 * 
 * @author Hans Joachim Herbertz
 * @created May 21, 2003
 */
public class NetworkRequest implements Runnable,ActionListener {
	/**
	 * Inet Server address and port.*/
	private URL address = null;
	/**
	 * Headers to send; headers will be send unchanged!:*/
	private String headers = null;
	/**
	 * Listener for progress. */
	private ProgressListener listener = null;
	/**
	 * Response data. */
	private byte[] response=null;
	
	/**
	 * Timer for ui progress for 
	 * progress monitoring is not yet implemented.
	 */
	private Timer timer=null;
	
	public NetworkRequest(URL address) {
		super();
		this.address = address;
	}

	public void sendRequest(String headers) {
		this.headers = headers;
		new Thread(this).start();
		timer=new Timer(500,this);
		timer.start();
		fireEvent(counter);
	}

	public byte[] getResposne() {
		return response;	
	}
	
	private void fireEvent(int state) {
			ProgressEvent event=new ProgressEvent(this,state);
			fireEvent(event);	
	}
	
	private void fireEvent(ProgressEvent e) {
		if (listener!=null) {
			listener.progress(e);		
		}
	}
	public void run() {
		
		try {
			Socket socket=new Socket(address.getHost(),address.getPort());
			socket.setSoTimeout(30000);
			OutputStream out=socket.getOutputStream();
			out.write(headers.getBytes());
			out.flush();
			BufferedInputStream in=new BufferedInputStream(socket.getInputStream());
			byte[] buffer=new byte[64];
			int read=0;
			ByteArrayOutputStream stream=new ByteArrayOutputStream();
			while((read=in.read(buffer))>0) {
				stream.write(buffer,0,read);
			}
			in.close();
			out.close();
			socket.close();
			stream.close();
			response=stream.toByteArray();
			timer.stop();
			fireEvent(ProgressEvent.MAX);
		} catch (Exception  e) {
			timer.stop();
			ProgressEvent event=new ProgressEvent(this,ProgressEvent.MAX);
			event.setError(e);
			fireEvent(event);
		}
		fireEvent(ProgressEvent.MIN);
	}

	/**
	 * Sets the listener.
	 * @param listener The listener to set
	 */
	public void setListener(ProgressListener listener) {
		this.listener = listener;
	}

	/**
	 * Some nice progress events
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	public void actionPerformed(ActionEvent e) {
	   	fireEvent(counter);
	   	counter=counter+5;
	   	if (counter>=ProgressEvent.MAX) counter=ProgressEvent.MIN;
	}
	private int counter=5;

}
